using System;
using System.Collections.Generic;
using System.Text;

using System.Xml;

namespace ClientGUI
{
    /// <summary>
    /// This module is for in-text markup.  For example:
    /// [para] this is a [bold]paragraph.[/bold][/para]
    /// The markup would be the bold tag.
    /// </summary>
	class Markup: Module, ITextAble, IWordAble
	{
		bool am_bold = false;
		String my_tag;
		String my_tagname;
		Word[] my_words;


        /// <param name="doc">The section of the document which
        /// this represents.</param>
        /// <param name="parent">The parent of this module</param>
        /// <param name="host">The host of this which does the
        /// actual display management.</param>
        /// <param name="config">A part of an xml document representing
        /// configuration information for this specific instance of this module.
        /// </param>
        /// <param name="tagconfig">Configuration of Children and Attributes</param>
		public Markup(XmlNode doc, Module parent,
			DisplayDocument host, XmlNode config,
            TagConfig tagconfig)
			: base(doc, parent, host, tagconfig)
		{
			StringBuilder tag = new StringBuilder();
			tag.Append(doc.Name);
			for (int i = 0; i < doc.Attributes.Count; ++i) {
				tag.Append(" ");
				tag.Append(doc.Attributes[i].Name);
				tag.Append("=\"");
				tag.Append(doc.Attributes[i].Value.ToString());
				tag.Append("\"");
			}
			my_tag = tag.ToString();
			my_tagname = doc.Name;

			am_bold = bool.Parse(config.SelectSingleNode("Bold").
				Attributes.GetNamedItem("bool").Value);
		}

		#region ITextAble Members

		public bool Pure
		{
			get
			{
				foreach (Module child in Children) {
					if ((child as ITextAble) == null)
						return false;
					if (!(child as ITextAble).Pure)
						return false;
				}
				return true;
			}
		}

		public string Text
		{
			get
			{
				StringBuilder text = new StringBuilder();
				text.Append("<" + my_tag + ">");
				foreach (Module kid in Children) {
					if ((kid as ITextAble) != null) {
						text.Append((kid as ITextAble).Text);
					}
				}
				text.Append("</" + my_tagname + ">");
				text.Append(" ");
				return text.ToString();
			}
		}
		#endregion


		private void setup()
		{
			int size = 0;
			foreach (Module kid in my_kids) {
				IWordAble kidw = kid as IWordAble;
				if (kidw == null)
					throw new Exception("Markup tag has non text child");
				size += kidw.Length;
			}
			my_words = new Word[size];
			int l = 0;
			foreach (Module kid in my_kids) {
				IWordAble kidw = kid as IWordAble;
				for (int i = 0; i < kidw.Length; ++i) {
					if (am_bold) {
						my_words[l] = new Word(kidw[i].Text, true);
					} else 
						my_words[l] = kidw[i];
					++l;
				}
			}
		}

		#region IWordAble Members

		public Word this[int index]
		{
			get
			{
				setup();
				return my_words[index];
			}
		}

		public int Length
		{
			get
			{
				setup();
				return my_words.Length;
			}
		}

		#endregion

        public override ClientGUI.Modules.Drawing.DisplayArea GetDisplayArea()
        {
            return new Modules.Drawing.BlankDisplayArea();
        }
    }
}
